package com.ruoyi.sjl.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import com.ruoyi.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Component
public class RescueWebSocketHandler extends TextWebSocketHandler {
    @Autowired
    private RedisService redisService;
    // 存储用户和商家的连接
    private static final Map<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();
    private static final Map<String, WebSocketSession> merchantSessions = new ConcurrentHashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String path = Objects.requireNonNull(session.getUri()).getPath();
        String[] parts = path.split("/");
        String type = parts[2]; // user or merchant
        String id = parts[3];
        if ("user".equals(type)) {
            userSessions.put(id, session);
        } else if ("merchant".equals(type)) {
            merchantSessions.put(id, session);
        }
        System.out.println("WebSocket connected: " + type + " - " + id);
    }
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 解析消息（可以约定 JSON 格式）
        Map<String, Object> msgMap = objectMapper.readValue(message.getPayload(), Map.class);
        String type = (String) msgMap.get("type");
        // 处理心跳
        if ("heartbeat".equals(type)) {
        // session.sendMessage(new TextMessage(objectMapper.writeValueAsString(Map.of("type", "heartbeatAck"))));
        // 使用google Guava  实现jdk9的Map.of()
           session.sendMessage(new TextMessage(objectMapper.writeValueAsString(ImmutableMap.of("type", "heartbeatAck"))));
        }
        // 处理其他客户端消息（可调用业务 Service）
        System.out.println("Received message: " + message.getPayload());
    }
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        userSessions.values().remove(session);
        merchantSessions.values().remove(session);
        System.out.println("WebSocket closed: " + session.getId());
    }
    public void notifyUser(String userId, String type,Map<String, Object> data) {
        WebSocketSession session = userSessions.get(userId);
        if (session != null && session.isOpen()) {
            try {
                Map<String, Object> message = new HashMap<>();
                message.put("type", type);
                message.put("data", data);
                String jsonMessage = objectMapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(jsonMessage));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void notifyMerchant(String merchantId, String type,Map<String, Object>  data) {
        WebSocketSession session = merchantSessions.get(merchantId);
        if (session != null && session.isOpen()) {
            try {
                Map<String, Object> message = new HashMap<>();
                message.put("type", type);
                message.put("data", data);
                String jsonMessage = objectMapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(jsonMessage));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void broadcastMerchantsToNearby(
                                           List<RedisGeoCommands.GeoLocation<String>> merchants,
                                           String type,
                                           Map<String, Object>  data) {
        // 遍历附近商家，逐个推送消息
        merchants.forEach(merchant -> {
            // 1. 获取商家的WebSocket连接（merchant.getName()是商家ID，与session缓存key一致）
            WebSocketSession session = merchantSessions.get(merchant.getName());
            if (session == null || !session.isOpen()) {
                log.warn("商家{}的WebSocket连接未建立或已关闭，跳过广播", merchant.getName());
                return;
            }
            try {
                // 2. 构建统一消息体（type + rescueId + data）
                Map<String, Object> message = new HashMap<>();
                message.put("type", type); // 消息类型，前端用于区分业务
                message.put("data", data);          // 动态数据，可传任意结构（Map/实体类都可）
                // 3. 序列化消息为JSON，发送给商家
                String jsonMessage = objectMapper.writeValueAsString(message);
                session.sendMessage(new TextMessage(jsonMessage));

                log.info("已向商家{}，广播动态数据：{}", merchant.getName(),  data);
            } catch (Exception e) {
                log.error("向商家{}广播动态数据{}失败", merchant.getName(), data, e);
                // 可加重试逻辑（比如重试1次），避免网络波动导致消息丢失
            }
        });
    }

}
